package com.java110.mall.cart.cmd.storeOrder;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.annotation.Java110Transactional;
import com.java110.core.context.CmdContextUtils;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.dto.data.DatabusDataDto;
import com.java110.dto.storeOrder.StoreOrderCartDto;
import com.java110.dto.storeOrder.StoreOrderCartEventDto;
import com.java110.dto.storeOrder.StoreOrderDto;
import com.java110.intf.cart.IStoreOrderCartEventInnerServiceSMO;
import com.java110.intf.cart.IStoreOrderCartInnerServiceSMO;
import com.java110.intf.cart.IStoreOrderInnerServiceSMO;
import com.java110.intf.cart.IStoreOrderWriteoffV1InnerServiceSMO;
import com.java110.intf.chain.IDataBusInnerServiceSMO;
import com.java110.po.storeOrder.StoreOrderCartEventPo;
import com.java110.po.storeOrder.StoreOrderCartPo;
import com.java110.po.storeOrder.StoreOrderPo;
import com.java110.po.storeOrderWriteoff.StoreOrderWriteoffPo;
import com.java110.utils.cache.MappingCache;
import com.java110.utils.constant.MappingConstant;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.ListUtil;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.List;

@Java110Cmd(serviceCode = "storeOrder.stockUpStoreOrder")
public class StockUpStoreOrderCmd extends Cmd {

    @Autowired
    private IStoreOrderInnerServiceSMO storeOrderInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderCartInnerServiceSMO storeOrderCartInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderCartEventInnerServiceSMO storeOrderCartEventInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderWriteoffV1InnerServiceSMO storeOrderWriteoffV1InnerServiceSMOImpl;

    @Autowired
    private IDataBusInnerServiceSMO dataBusInnerServiceSMOImpl;

    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException {
        Assert.hasKeyAndValue(reqJson, "orderId", "请求报文中未包含orderId");
        Assert.hasKeyAndValue(reqJson, "shopId", "shopId不能为空");
        Assert.hasKeyAndValue(reqJson, "extOrderId", "核销编号不能为空");
        Assert.hasKeyAndValue(reqJson, "stockUpRemark", "备货说明不能为空");
        Assert.hasKey(reqJson, "carts", "未包含备货商品");

        JSONArray carts = reqJson.getJSONArray("carts");
        if (ListUtil.isNull(carts)) {
            throw new CmdException("未包含备货商品");
        }

    }

    @Override
    @Java110Transactional
    public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException {

        String userId = CmdContextUtils.getUserId(context);
        // todo 将订单状态修改为上门核销
        StoreOrderDto storeOrderDto = new StoreOrderDto();
        storeOrderDto.setOrderId(reqJson.getString("orderId"));
        List<StoreOrderDto> storeOrderDtos = storeOrderInnerServiceSMOImpl.queryStoreOrders(storeOrderDto);
        Assert.listOnlyOne(storeOrderDtos, "订单不存在");
        StoreOrderPo storeOrderPo = new StoreOrderPo();
        storeOrderPo.setOrderId(storeOrderDtos.get(0).getOrderId());
        storeOrderPo.setState(StoreOrderDto.STATE_STORE_VERIFICATION);
        storeOrderInnerServiceSMOImpl.updateStoreOrder(storeOrderPo);

        // todo 将备货完成商品状态修改为备货完成

        StoreOrderCartDto storeOrderCartDto = new StoreOrderCartDto();
        storeOrderCartDto.setOrderId(reqJson.getString("orderId"));
        List<StoreOrderCartDto> storeOrderCartDtos
                = storeOrderCartInnerServiceSMOImpl.queryStoreOrderCarts(storeOrderCartDto);
        if (ListUtil.isNull(storeOrderCartDtos)) {
            return;
        }
        JSONArray carts = reqJson.getJSONArray("carts");
        StoreOrderCartPo storeOrderCartPo = null;
        BigDecimal refundAmount = new BigDecimal("0.0");
        for (StoreOrderCartDto tmpStoreOrderCartDto : storeOrderCartDtos) {
            storeOrderCartPo = new StoreOrderCartPo();
            storeOrderCartPo.setCartId(tmpStoreOrderCartDto.getCartId());
            storeOrderCartPo.setState(StoreOrderCartDto.STATE_STORE_VERIFICATION);
            if (!hasInVerification(tmpStoreOrderCartDto, carts)) {
                storeOrderCartPo.setState(StoreOrderCartDto.STATE_RETURN_MONEY);
                refundAmount = refundAmount.add(new BigDecimal(tmpStoreOrderCartDto.getPayPrice()));
            }
            storeOrderCartInnerServiceSMOImpl.updateStoreOrderCart(storeOrderCartPo);

            StoreOrderCartEventPo storeOrderCartEventPo = new StoreOrderCartEventPo();
            storeOrderCartEventPo.setCartId(tmpStoreOrderCartDto.getCartId());
            storeOrderCartEventPo.setOrderId(tmpStoreOrderCartDto.getOrderId());
            storeOrderCartEventPo.setEventId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_eventId));
            storeOrderCartEventPo.setEventObjType("S");
            storeOrderCartEventPo.setEventObjId(userId);
            storeOrderCartEventPo.setEventMsg(reqJson.getString("stockUpRemark") + "-备货完成,核销单号：" + reqJson.getString("extOrderId"));
            if (!hasInVerification(tmpStoreOrderCartDto, carts)) {
                storeOrderCartEventPo.setEventMsg(reqJson.getString("stockUpRemark") + "-缺货已退款");
            }
            storeOrderCartEventPo.setShopId(tmpStoreOrderCartDto.getShopId());
            storeOrderCartEventPo.setEventType(StoreOrderCartEventDto.EVENT_TYPE_EXPEDITING_SENDING);
            // todo 写入备货完成时间
            int flag = storeOrderCartEventInnerServiceSMOImpl.saveStoreOrderCartEvent(storeOrderCartEventPo);
            if (flag < 1) {
                throw new IllegalArgumentException("保存购物车事件失败");
            }
        }

        StoreOrderWriteoffPo storeOrderWriteoffPo = new StoreOrderWriteoffPo();
        storeOrderWriteoffPo.setRemark(reqJson.getString("stockUpRemark"));
        storeOrderWriteoffPo.setOrderId(reqJson.getString("orderId"));
        storeOrderWriteoffPo.setWoNum(reqJson.getString("extOrderId"));
        storeOrderWriteoffV1InnerServiceSMOImpl.updateStoreOrderWriteoff(storeOrderWriteoffPo);

        // 触发databus
        dataBusInnerServiceSMOImpl.databusData(new DatabusDataDto(DatabusDataDto.FINISH_READY_ORDER,reqJson.getString("orderId")));


        // todo 将缺货 商品 触发退款
        if (refundAmount.doubleValue() <= 0) {
            return;
        }
        // todo 触发退款 注意演示环境不触发退款
        String env = MappingCache.getValue(MappingConstant.ENV_DOMAIN, "ENV_PAY");
        if ("DEV".equals(env)) {
            return;
        }
    }

    /**
     * 校验是否备货完成
     *
     * @param tmpStoreOrderCartDto
     * @param carts
     * @return
     */
    private boolean hasInVerification(StoreOrderCartDto tmpStoreOrderCartDto, JSONArray carts) {
        for (int cartIndex = 0; cartIndex < carts.size(); cartIndex++) {
            if (tmpStoreOrderCartDto.getCartId().equals(carts.getJSONObject(cartIndex).getString("cartId"))) {
                return true;
            }
        }
        return false;
    }
}
